trips <- trips %>% filter(duracion_recorrido >= 300 & duracion_recorrido <=3600) #Filtramos los minutos necesariosTrabajo Practico 1 de Laboratorio de Datos
Introducción
En este trabajo, usaremos lo aprendido en clase para analizar, manipular, describir y explorar con diferentes tipos de datos. Para demostrar esto, trabajaremos con dos datasets: los datos del clima recolectados en el Aeroparque durante todo el año de 2022 y un muestra de 10.000 casos de viajes de usuarios de Ecobici.
Para empezar, trabajaremos con el dataset de usuarios de Ecobici.
Dataset: usuarios de Ecobici
Análisis descriptivo
Empecemos describiendo las variables que presenta este dataset (en negrita se especifica su variable en el df):
La fecha en la que se hizo el reccorido (fecha)
La duración del recorrido (duracion_recorrido) expresada en segundos,
La fecha de partida y de llegada con su dia y hora (fecha_origen_recorrido y fecha_destino_recorrido respectivamente)
las estaciones de partida y salida de cada viaje (nombre_estacion_origen y nombre_estacion_destino)
Datos referidos a cada estacion (diferenciados por origen y destino, cambiando “_origen/ _destino” al final de la variable en el df) como su longtitud (long_estacion_), latitud (lat_estacion), direccion (direccion_estacion), identificador (id_estacion) y nombre (nombre_estacion)
El identificador de cada viaje realizado ( Id_recorrido)
El identificador del usuario que uso la bicicleta (id_usuario)
El genero de la persona (Género)
El modelo de la bicicleta (modelo_bicicleta)
Antes de manejar los datos, como dicta la consigna, vamos a establecer como criterio de selección de los viajes, aquellos recorridos comprendidos entre 5 minutos y 1 hora. Es decir, entre 300 y 3600 segundos:
Ahora si, teniendo los datos necesarios para empezar a realizar un análisis descriptivo de este dataset, vamos a comenzar a explorar desde aspectos que resulten más “sencillos”; y luego, a medida de que recolectemos suficiente información, iremos complejizando y generando hipótesis basadas en los resultados anteriores.
En primer lugar, lo primero que se nos ocurre ver son los modelos de bicicletas presentados en el dataset y la cantidad de elecciones de cada uno, para ver si encontramos alguna diferencia notable entre estas variables:
trips %>% count(modelo_bicicleta) #Visualiza en una tabla los modelos de bicleta y hace una sumatoria de cuantas veces se utilizó# A tibble: 2 × 2
modelo_bicicleta n
<chr> <int>
1 FIT 5107
2 ICONIC 4146
Acá podemos ver que no hay mucha diferencia entre cantidad de modelos, que, aunque parezca un análisis simple, nos permite entender que no hay una preferencia por un modelo sobre otro a la hora de elegir qué EcoBici usar.
Podemos también hacer lo mismo con el género de los usuarios con la siguiente tabla:
genero_dataset <- trips %>%
distinct(id_usuario, Género) %>% #Tomo los usuarios no repetidos
drop_na()%>%
count(Género) %>% #Cuento cuantas veces aparece cada genero
mutate(Porcentaje = round(n / sum(n) * 100)) #Y hago su porcentaje
genero_dataset# A tibble: 3 × 3
Género n Porcentaje
<chr> <int> <dbl>
1 FEMALE 2555 32
2 MALE 4494 57
3 OTHER 902 11
Cabe aclarar, que en esta última tabla (o tibble) se muestra el género de los usuarios que usaron alguna EcoBici, pero sin repetidos, ya que muchos de estos usuarios han hecho más de un viaje, y el dataset dado guarda datos según recorridos individuales. Para mejorar la visualización, decidimos incluir un gráfico de barras para explayar esta información mejor:
#Grafico que muestra la frecuencia de las bicis usadas por cada genero
ggplot(genero_dataset, mapping = aes(
x=Género,
y=n,
fill=Género)) + #X= genero, y= frecuencia
geom_col() + #Se crea un grafico de barras
labs(x = "Género", y = "Frecuencia", title = "Distribución de Género") +
geom_label(aes(label = paste0(Porcentaje, "%")))Es importante ir más allá de los datos de los usuarios en sí y de sus recorridos individuales, como su género o el modelo de bicicleta que usaron, para pasar a centrarse en los datos de una manera más global, para esto, podemos ver por ejemplo el uso de las Ecobicis a lo largo del año de la siguiente manera:
trips_trimestral <-trips %>% mutate("trimestre" = quarters(fecha)) %>% count(trimestre) %>%
mutate(trimestre = recode(trimestre,
"Q1" = "Trimestre 1",
"Q2" = "Trimestre 2",
"Q3" = "Trimestre 3",
"Q4" = "Trimestre 4"
))%>%
mutate(Porcentaje = round(n / sum(n) * 100))
trips_trimestral# A tibble: 4 × 3
trimestre n Porcentaje
<chr> <int> <dbl>
1 Trimestre 1 2103 23
2 Trimestre 2 2182 24
3 Trimestre 3 2370 26
4 Trimestre 4 2598 28
Acá podemos ver la información de las fechas en las que se hicieron los viajes de una manera más simplificada, al dividir el año en 4 cuartos (quedando trimestres), vemos como a lo largo del año los viajes en EcoBici van aumentando. Esto tambien lo podemos ver con el siguiente gráfico:
ggplot(trips_trimestral,
mapping =aes(
x=trimestre,
y=n,
fill =trimestre)) +
geom_col() +
labs(x = "Trimestre", y = "Frecuencia", title = "Distribución de uso por trimestre")+
geom_label(aes(label = paste0(Porcentaje, "%")))Ahora se puede visualizar mucho mejor el aumento de uso en Ecobici a lo largo del año, con una diferencia notable entre el principio y el final del año.
También nos podemos centrar en variables no discretas, como por ejemplo la duración del trayecto. Al haber más cantidad de datos únicos, la mejor manera de ver la duración de los trayectos es usando un gráfico de puntos:
trips <- trips %>% mutate(duracion_en_min = duracion_recorrido/60)
ggplot(trips %>% mutate(trips,"Trimestre" = quarters(fecha)), mapping=aes(
x=fecha,
y=duracion_en_min,
color=Trimestre
)) + geom_point() + labs(x = "Fecha", y = "Duración de viajes (en minutos)", title = "Duración de cada viaje (en minutos) en todo el año, según el trimestre")Y también con este gráfico similar al anterior pero dividido más claramente por trimestres.
#Se crea dataset diferenciado en cuatrimestres y que sume la cantidad de recorridos por dia
trips_duracion_diaria <- trips %>%
mutate("Trimestre" = quarters(fecha))%>%
mutate(Trimestre = recode(Trimestre,
"Q1" = "Trimestre 1",
"Q2" = "Trimestre 2",
"Q3" = "Trimestre 3",
"Q4" = "Trimestre 4"
))%>%
group_by(fecha, Trimestre)%>%
mutate(Duración_Total = sum(duracion_recorrido/60))%>% #Nueva columna con la duración por día en minutos
distinct(Duración_Total) #Tomo fechas unicas
#Se crea gráfico de puntos para visualizar cuántos minutos se reccorieron por cada día
ggplot(trips_duracion_diaria,
mapping=aes(
x=fecha,
y=Duración_Total
)) +
labs(x = "Fecha", y = "Duración de los viajes (en minutos)", title = "Duracion de los viajes segun el trimestre")+
geom_point(aes(color=Trimestre))+ #Gráfico de puntos
facet_wrap(~ Trimestre, ncol = 4, scales = "free_x") #Divido en 4 graficos según cuál sea su cuatrimestreCon los casos extremos ya removidos, se puede apreciar la duración de los viajes a lo largo del año, y para facilitar la visualización agregamos una distinción por cuartil del año usando colores, simplificando el diseño del gráfico.
Para presentar información adicional, presentamos el promedio y la mediana de los viajes realizados por minuto
trips_info <- trips %>%
summarise(promedio_minutos = round(mean(duracion_en_min)),
mediana_minuto= round(median(duracion_en_min)))
trips_info# A tibble: 1 × 2
promedio_minutos mediana_minuto
<dbl> <dbl>
1 19 16
Para también poder visualizar la cantidad de viajes que hizo cada usuario, usamos el siguiente:
viajesDeCadaUsuario<-trips %>%
group_by(id_usuario) %>% #Agrupo por usuario
summarize(viajesTotales= n()) #Sumo los viajes realizados por cada persona
viajesTotalesPorPersona <- viajesDeCadaUsuario %>%
group_by(viajesTotales) %>%
summarize(cantidad_personas = n()) %>% #Sumo la cantidad de personas que hicieron la misma cantidad de viajes
arrange(viajesTotales) #Las ordeno de menor a mayor segun su cantidad de viajes
viajesTotalesPorPersona# A tibble: 6 × 2
viajesTotales cantidad_personas
<int> <int>
1 1 6975
2 2 825
3 3 149
4 4 36
5 5 6
6 7 1
Acá podemos apreciar como la cantidad de personas que hicieron múltiples viajes baja drásticamente cuando la cantidad de viajes totales sube, permitiéndonos ver que la mayor parte de los usuarios usó el sistema una única vez.
Para analizar las tendencias de uso de las estaciones de forma más detallada, hemos identificado las 20 estaciones más populares tanto de partida como de llegada.
top_estaciones_origen <- trips %>%
select(nombre_estacion_origen) %>% #Tomo la columna de los nombres
group_by(nombre_estacion_origen) %>%#las ordeno por nombre
summarise(conteo = n()) %>% #Cuento cuantas veces se repiten
arrange(desc(conteo))#las ordeno de mayor a menor
primeras_20_estaciones <- head(top_estaciones_origen, 20) #Tomo las primeras 20
primeras_20_estaciones# A tibble: 20 × 2
nombre_estacion_origen conteo
<chr> <int>
1 147 - Constitución 119
2 014 - Pacifico 111
3 130 - RETIRO II 110
4 054 - Acuña de Figueroa 101
5 008 - Congreso 97
6 160 - Godoy Cruz y Libertador 86
7 005 - Plaza Italia 81
8 292 - PLAZA BOLIVIA 81
9 009 - Parque Las Heras 80
10 131- HOSPITAL DE CLÍNICAS 79
11 096 - Carlos Gardel 78
12 066 - Billinghurst 74
13 121 - YATAY 71
14 161 - Humahuaca 70
15 025 - Plaza Guemes 67
16 255 - BARRANCAS DE BELGRANO 66
17 001 - FACULTAD DE DERECHO 65
18 033 - Facultad de Medicina 64
19 065 - Julián Álvarez 64
20 029 - Parque Centenario 62
top_estaciones_destino <- trips %>%
select(nombre_estacion_destino) %>%#Tomo la columna de los nombres
group_by(nombre_estacion_destino) %>%#las ordeno por nombre
summarise(conteo = n()) %>%#Cuento cuantas veces se repiten
arrange(desc(conteo))#las ordeno de mayor a menor
primeras_20_estaciones <- head(top_estaciones_destino, 20) #Tomo las primeras 20
primeras_20_estaciones# A tibble: 20 × 2
nombre_estacion_destino conteo
<chr> <int>
1 147 - Constitución 125
2 014 - Pacifico 106
3 008 - Congreso 100
4 160 - Godoy Cruz y Libertador 95
5 005 - Plaza Italia 85
6 131- HOSPITAL DE CLÍNICAS 85
7 001 - FACULTAD DE DERECHO 84
8 130 - RETIRO II 83
9 017 - Plaza Almagro 80
10 066 - Billinghurst 78
11 096 - Carlos Gardel 78
12 054 - Acuña de Figueroa 73
13 152 - JULIETA LANTERI 72
14 029 - Parque Centenario 68
15 009 - Parque Las Heras 67
16 150 - RODRIGO BUENO 66
17 025 - Plaza Guemes 64
18 281 - Villa Urquiza 64
19 044 - Ecoparque 63
20 085 - AGUERO 63
Comparando estas dos tablas, podemos ver que las estaciones más populares de salida son también muy populares como estaciones de llegada, mostrando que o muchas personas empiezan el trayecto en el mismo lugar en donde lo terminan, o simplemente que muchas personas van a un lugar y vuelven a salir desde ahí.
Además, presentamos un gráfico que permite visualizar la distribución de la distancia recorrida en bicicleta por los usuarios. Hemos calculado la distancia en metros entre las estaciones de origen y destino para cada viaje (usando el geosphere); Luego, hemos agrupado estas distancias en categorías para comprender mejor los patrones de uso.
trips_distancia <- trips %>%
select(Id_recorrido, long_estacion_origen, lat_estacion_origen, long_estacion_destino, lat_estacion_destino) %>%
mutate(Distancia_metros = round(distVincentySphere(cbind(long_estacion_origen, lat_estacion_origen), cbind(long_estacion_destino, lat_estacion_destino))))%>%
mutate(Distancia_grupos = case_when(
Distancia_metros >= 0 & Distancia_metros <= 2000 ~ "0-2000",
Distancia_metros > 2000 & Distancia_metros <= 4000 ~ "2000-4000",
Distancia_metros > 4000 & Distancia_metros <= 6000 ~ "4000-6000",
Distancia_metros > 6000 & Distancia_metros <= 8000 ~ "6000-8000",
Distancia_metros > 8000 ~ "8000+"))%>%
arrange(Distancia_metros)
grupo_frecuencia <- trips_distancia %>%
count(Distancia_grupos)%>%
mutate(Porcentaje = round(n / sum(n) * 100))
ggplot(grupo_frecuencia,
mapping = aes(
x=Distancia_grupos,
y=n,
fill=Distancia_grupos))+
geom_col() +
labs(x = "Metros Recorridos", y = "Cantidad Usuarios", title = "Distibucion por distancia(metros)") +
geom_label(aes(label = paste0(Porcentaje, "%")))Para obtener una representación visual de la distribución y ubicación de las estaciones, hemos creado un mapa interactivo a traves del leaflet.
todas_estaciones <- trips %>%
select(nombre_estacion_origen) %>%
group_by(nombre_estacion_origen) %>%
summarise(conteo = n()) %>%
arrange(desc(conteo))
result <- inner_join(todas_estaciones, trips, by = "nombre_estacion_origen")%>%
select(nombre_estacion_origen, lat_estacion_origen, long_estacion_origen) %>%
distinct(nombre_estacion_origen, lat_estacion_origen, long_estacion_origen)
mapa <- leaflet() %>%
addTiles() %>%
addMarkers(data=result,
lng = result$long_estacion_origen,
lat = result$lat_estacion_origen,
clusterOptions = markerClusterOptions())
mapaEn este mapa, destacamos las 100 estaciones más populares utilizadas como puntos de inicio para los viajes en bicicleta.
top_estaciones <- trips %>%
select(nombre_estacion_origen) %>%
group_by(nombre_estacion_origen) %>%
summarise(conteo = n()) %>%
arrange(desc(conteo))
primeras_100_estaciones <- top_estaciones %>%
head(100)
result <- inner_join(primeras_100_estaciones, trips, by = "nombre_estacion_origen")%>%
select(nombre_estacion_origen, lat_estacion_origen, long_estacion_origen) %>%
distinct(nombre_estacion_origen, lat_estacion_origen, long_estacion_origen)
mapa <- leaflet() %>%
addTiles() %>%
addMarkers(data=result,
lng = result$long_estacion_origen,
lat = result$lat_estacion_origen,
clusterOptions = markerClusterOptions())
mapaDataset: Datos del clima
Análisis descriptivo
Empecemos describiendo las variables que presenta este dataset: En primer lugar vemos la fecha (date) en la que se registró cada dato del clima. Siguiendo con tavg, tmin y tmax, que son la temperatura promedio, la temperatura mínima y la temperatura máxima, respectivamente. Continuando con prcp, snow, wdir, wspd, wpgt, que son las precipitaciones registradas (lluvias, en mm.c.d.a., es decir milímetros de columna de agua), nieve, wind direction (dirección del viento, en grados, con 0 apuntando al sur), wind speed (velocidad del viento, en km/h) y ráfaga de viento, respectivamente. Terminando con pres y tsun, que es la presión atmosférica (en hPa), y duración del sol, respectivamente.
Por lo visto, encontramos que hay algunas variables que no tienen datos, estas son: snow, wpgt y tsun, que representan la cantidad de nieve, la r. Por lo tanto, lo primero que hacemos es sacar estas columnas, porque no podemos trabajar con algo que no tiene datos.
colnames(datos_clima)[1] <- "fecha"
datos_clima <- datos_clima %>% select(fecha,tavg,tmin,tmax,prcp,wdir,wspd,pres)Empecemos con el análisis descriptivo de este dataset:
En primer lugar queremos hablar sobre el cambio de la temperatura a lo largo del año, en este primer gráfico podemos ver que la temperatura promedio desciende de enero a julio y asciende de julio a enero, con una linea de tendencia verde para mejor ver este cambio.
ggplot(datos_clima,mapping=aes(
x=fecha,
y=tavg)) + geom_line(aes(y=tavg),color="black") + geom_smooth(se=F,color="green") +
labs(x = "Fecha", y = "Temperatura Promedio(tavg)", title = "Temperatura promedio por día a lo largo del año")En el siguiente gráfico podemos ver lo mismo, sólo que agregando las temperaturas mínimas (azul) y máximas (rojo).
ggplot(datos_clima,mapping=aes(
x=fecha,
y=tavg)) + geom_line(aes(y=tavg),color="black") +
geom_line(aes(y=tmin),color="blue") +
geom_line(aes(y=tmax), color="red") +
geom_smooth(se=F, color="green")+
labs(x = "Fecha", y = "Temperatura Promedio(tavg)", title = "Temperatura promedio por día a lo largo del año")Así podemos apreciar con mucha más información los cambios de temperatura anuales.
También consideramos importante analizar los datos dados acerca del viento, los cuales mostramos en el siguiente gráfico.
analisis_viento <- datos_clima %>%
select(wspd) %>%
mutate(tipo_viento = case_when(wspd > 1 & wspd <= 5 ~"calmado",
wspd > 5 & wspd <= 11 ~"brisa",
wspd > 11 & wspd <= 19~"leve",
wspd > 19 & wspd <= 28~"moderado",
wspd > 28 ~"regular"))
analisis_viento# A tibble: 365 × 2
wspd tipo_viento
<dbl> <chr>
1 14.4 leve
2 9.6 brisa
3 12.5 leve
4 18.3 leve
5 24.2 moderado
6 22.7 moderado
7 20.6 moderado
8 21.9 moderado
9 19.6 moderado
10 11.5 leve
# ℹ 355 more rows
Respecto a la velocidad del viento, nos basamos en el Servicio Metereológico Nacional, para ver la clasificación de la intensidad del viento:
Calmado: de 1km/h a 5km/h.
Brisa: de 5km/h a 11km/h.
Leve: de 11km/h a 19km/h.
Moderado: de 19km/h a 28km/h.
Regular: de 28km/h a 38km/h.
analisis_viento <- datos_clima %>% select(fecha,wspd) %>% mutate(tipo_viento = case_when(wspd > 1 & wspd <= 5 ~"calmado", wspd > 5 & wspd <= 11 ~"brisa", wspd > 11 & wspd <= 19~"leve", wspd > 19 & wspd <= 28~"moderado", wspd > 28 ~"regular"),fecha) ggplot(analisis_viento, mapping = aes ( x = fecha, y=wspd,color=tipo_viento )) + geom_point()+ labs(x = "Fecha", y = "Velocidad del viento (wspd)", title = "Intensidad del viento por día")
Lo que podemos ver es que no hay ninguna relación entre época del año (ya sea día, mes, o estación) y velocidad del viento. Vemos que por lo general en un mismo mes la velocidad del viento puede ir desde calmada hasta moderado, o de brisa a regular, sin problema alguno.
Ahora, vamos a trabajar con los dias que llovieron, usaron la siguiente tabla:
datos_clima %>%
summarize(DíasTotales=365,
DíasConLluvia= sum(datos_clima$prcp> 0.0,na.rm=TRUE),
DíasSinLluvia=DíasTotales-DíasConLluvia,
PorcentajeDeDíasConLluvia= round((DíasConLluvia*100)/DíasTotales,2))# A tibble: 1 × 4
DíasTotales DíasConLluvia DíasSinLluvia PorcentajeDeDíasConLluvia
<dbl> <int> <dbl> <dbl>
1 365 97 268 26.6
Ya con esto, podemos ver no solo la cantidad de dias que llovieron, sino tambien el porcentaje, y desde aquí podemos empezar a centrarnos en los días que hubo alguna precipitación específicamente, discriminandolo en la siguiente tabla y luego explayándolos en un gráfico:
dias_con_lluvia<-datos_clima %>%
filter(prcp>0.0)
dias_con_lluvia# A tibble: 97 × 8
fecha tavg tmin tmax prcp wdir wspd pres
<date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl>
1 2022-01-01 24.8 20.7 29.1 2.3 344 14.4 1004.
2 2022-01-02 24.7 19.2 29.7 1.5 16 9.6 1005.
3 2022-01-03 27.9 24.1 31.7 6.7 81 12.5 1007.
4 2022-01-04 28.2 24.8 32.6 3.9 236 18.3 1006.
5 2022-01-11 29.4 24.7 34.9 0.1 355 13.5 1009.
6 2022-01-15 31.3 27.2 37 0.9 360 11.1 1007.
7 2022-01-16 27.2 22.3 35.6 4.8 303 13.5 1004.
8 2022-01-17 25.2 20.9 32.4 29.1 127 21.6 1008.
9 2022-01-18 23.8 22.8 27.5 17.1 91 32 1015.
10 2022-01-19 23.8 21.1 26.2 0.8 109 25.2 1016.
# ℹ 87 more rows
#Filtramos un caso extremo para que el gráfico se pueda visualizar correctamente.
ggplot(dias_con_lluvia %>% filter(prcp<50),mapping=aes(
x=fecha,
y=prcp, colour=prcp
)) + geom_point() + labs(x = "Fecha", y = "Precipitaciones (prcp)", title = "Precipitaciones a lo largo del año")Así, podemos ver de manera más clara la distribucion anual de días con lluvia, sin tener que centrarnos en días sin precipitaciones.
En el siguiente cuadro en vez de centrarnos en días individuales vamos a centrarnos en los meses del año:
meses_del_año <- datos_clima %>%
mutate(mes_del_año = months(fecha))
meses_del_año# A tibble: 365 × 9
fecha tavg tmin tmax prcp wdir wspd pres mes_del_año
<date> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <dbl> <chr>
1 2022-01-01 24.8 20.7 29.1 2.3 344 14.4 1004. January
2 2022-01-02 24.7 19.2 29.7 1.5 16 9.6 1005. January
3 2022-01-03 27.9 24.1 31.7 6.7 81 12.5 1007. January
4 2022-01-04 28.2 24.8 32.6 3.9 236 18.3 1006. January
5 2022-01-05 21.7 16.7 31.7 0 118 24.2 1016. January
6 2022-01-06 22.1 18.8 25.7 0 78 22.7 1017. January
7 2022-01-07 23.8 20.6 26.6 0 67 20.6 1016. January
8 2022-01-08 24.4 21.8 27.1 0 79 21.9 1016. January
9 2022-01-09 24.9 20.9 29.5 0 64 19.6 1015. January
10 2022-01-10 26.9 22.8 31.3 0 44 11.5 1012. January
# ℹ 355 more rows
Teniendo cada mes, ahora calculamos las precipitaciones totales por mes.
suma_lluvias_por_mes <- meses_del_año %>%
group_by(mes_del_año) %>%
summarize(SumaPrecipitaciones = sum(prcp, na.rm=TRUE))
suma_lluvias_por_mes# A tibble: 12 × 2
mes_del_año SumaPrecipitaciones
<chr> <dbl>
1 April 80
2 August 20.3
3 December 97.9
4 February 328.
5 January 104.
6 July 38.2
7 June 1.5
8 March 93.9
9 May 4.5
10 November 47.2
11 October 27.5
12 September 37.2
Ahora hagamos un gráfico para ver cuánto llovió cada mes :
suma_lluvias_por_mes$mes_del_año=factor(suma_lluvias_por_mes$mes_del_año,levels=month.name)
ggplot(suma_lluvias_por_mes, aes(x=mes_del_año,
y=SumaPrecipitaciones, fill=mes_del_año))+
geom_col()+ labs(title = "Precipitaciones por mes")En este gráfico de barras se puede ver de forma más clara no solo la cantidad de precipitaciones por mes sino también una clara y simple comparación entre todo el año.
Los siguientes gráficos muestran la velocidad del viento y la presión atmosférica respectivamente, ambas en función del día del año:
ggplot(datos_clima,mapping=aes(
x=fecha,
y=wspd
)) + geom_line(colour="blue") + geom_smooth(method="lm", colour="lightblue")+ theme_bw()+
labs(x = "Fecha", y = "Velocidad Del Viento (wspd)", title = "Velocidad del viento a lo largo del año")ggplot(datos_clima,mapping=aes(
x=fecha,
y=pres
)) + geom_line(colour="brown") + geom_smooth(method="lm", colour="purple") + theme_bw() + labs(x = "Fecha", y = "Presión Atmosférica (pres)", title = "Presión Atmosférica a lo largo del año")Como demuestra la línea de tendencia en azul, y a pesar de las aparentes grandes varianzas en las mediciones, estos saltos son tan frecuentes que los consideramos despreciables, al menos en función de la época del año.
Ahora, ya con el análisis descriptivo de los dataframes dados, podemos pasar a la parte de análisis exploratorio.
Análisis exploratorio
En esta parte del trabajo, nos centraremos en unir ambos data frames y buscar patrones en los datos dados, ya yendo más allá de los datos individuales que se muestran en las muestras dadas y analizando más en detalle las relaciones que podemos encontrar entre los datos.
Para empezar, vamos a crear un nuevo dataframe llamado “union” que contenga los datos de clima y de EcoBicis en el mismo documento, juntándolos en base a la fecha:
datos_clima <- datos_clima %>%
mutate(dia_del_año = row_number(),
estacion_año = case_when(
dia_del_año > 355 | dia_del_año <= 80 ~ "Verano",
dia_del_año > 80 & dia_del_año <= 172 ~ "Otoño",
dia_del_año > 172 & dia_del_año <= 264 ~ "Invierno",
dia_del_año > 264 & dia_del_año <= 355 ~ "Primavera"
),
trabajo = ifelse((dia_del_año) %% 7 %in% c(2,1), "Fin de semana", "Dia Laboral"))
union = trips %>%
inner_join(datos_clima, by="fecha")Desde aquí, el análisis exploratorio se simplifica en gran medida. Por ejemplo, ahora podemos relacionar la cantidad de viajes hechos en un día con el nivel de precipitacion (removiendo un caso particular con demasiada precipitación), usando un nuevo dataframe llamado “conteo_fechas” que cuenta la cantidad de viajes hechos en un día:
conteo_fechas <-trips %>%
group_by(fecha) %>%
summarise(Freq= n())conteo_fechas_expandido <- conteo_fechas %>% inner_join(datos_clima, by="fecha") %>% filter(prcp< 200) %>% filter(prcp>0)
ggplot(conteo_fechas_expandido,aes(
x=Freq,
y=prcp,
)) + geom_point() + geom_smooth(method="lm") +
theme_classic()+ labs(x = "Cantidad de viajes)", y = "Precipitaciones (prcp)", title = "Relación de viajes y las precipitaciones")Cómo se puede ver por la línea de tendencia, aunque sería más útil contar con más casos, se puede notar un simple patrón gracias a la línea de tendencia y es que se reduce la cantidad de viajes por día conforme aumenta la precipitación en determinado día. Sin embargo, sería útil centrarnos en relaciones más fuertes entre los dos dataframes.
Esto lo podemos realizar si pasamos a buscar patrones entre la duración de recorrido y la precipitación, para ver si las condiciones climáticas afectan la duración de cada viaje más que la cantidad de viajes totales en un día.
Para empezar, vamos a usar el dataframe anterior de “conteo_fechas” para ver la cantidad de viajes en cada día, y usar este numero para ver el promedio de duracion de viaje en cada día con lluvia, y buscar una correlacion entre estas variables, y con eso, explayar la informacion en un grafico para mejorar la visualizacion. Además, declaramos algunas variables que nos van a ayudar a filtrar los casos.
promedio_duracion <- union %>% group_by(fecha) %>%
summarize(promedio= mean(duracion_recorrido))
promedio_duracion# A tibble: 364 × 2
fecha promedio
<date> <dbl>
1 2022-01-01 1631.
2 2022-01-02 1212.
3 2022-01-03 1175.
4 2022-01-04 1069.
5 2022-01-05 1098.
6 2022-01-06 1375.
7 2022-01-07 1378.
8 2022-01-08 1589.
9 2022-01-09 978
10 2022-01-10 1164.
# ℹ 354 more rows
promedio_duracion_con_lluvia <- union %>%
filter(prcp>0) %>% group_by(fecha) %>%
summarize(promedio= mean(duracion_recorrido))
promedio_duracion_con_lluvia# A tibble: 96 × 2
fecha promedio
<date> <dbl>
1 2022-01-01 1631.
2 2022-01-02 1212.
3 2022-01-03 1175.
4 2022-01-04 1069.
5 2022-01-11 1070.
6 2022-01-15 1131.
7 2022-01-16 1657.
8 2022-01-17 1164.
9 2022-01-18 1079.
10 2022-01-19 1121.
# ℹ 86 more rows
dias_con_Precipitaciones <- union%>%
filter(prcp>0) %>% group_by(fecha) %>% select(fecha, prcp)
dias_con_Precipitaciones# A tibble: 2,152 × 2
# Groups: fecha [96]
fecha prcp
<date> <dbl>
1 2022-08-14 0.7
2 2022-01-11 0.1
3 2022-04-27 10.9
4 2022-03-17 0.2
5 2022-03-09 10.9
6 2022-12-28 0.2
7 2022-04-27 10.9
8 2022-03-10 0.2
9 2022-04-22 6.1
10 2022-03-29 2.9
# ℹ 2,142 more rows
diasConPrecipitacionesYPromedioDuracion<- distinct(dias_con_Precipitaciones%>%
inner_join(promedio_duracion_con_lluvia, by = "fecha"))
diasConPrecipitacionesYPromedioDuracion# A tibble: 96 × 3
# Groups: fecha [96]
fecha prcp promedio
<date> <dbl> <dbl>
1 2022-08-14 0.7 1575.
2 2022-01-11 0.1 1070.
3 2022-04-27 10.9 1149.
4 2022-03-17 0.2 1014.
5 2022-03-09 10.9 1124.
6 2022-12-28 0.2 1001.
7 2022-03-10 0.2 1051.
8 2022-04-22 6.1 1126.
9 2022-03-29 2.9 1002.
10 2022-03-21 2.6 1055.
# ℹ 86 more rows
Nuevamente, filtramos el caso aislado con una precipitación muy grande.
ggplot(diasConPrecipitacionesYPromedioDuracion %>% filter(prcp<40),
aes(
x = prcp,
y = promedio, colour=prcp
)) + geom_point() + geom_smooth(method="lm", colour="grey") +scale_color_continuous(low="lightblue", high = "blue")+
theme_light() + labs(x = "Precipitaciones(prcp)", y = "Promedio de duración de viajes", title = "Promedio de duración de viajes según las precipitaciones")En este grafico, el eje x son las precipitaciones por día y el eje y es el promedio de duracion de viaje en cada dia, contando solo los días con precipitaciones. Como se demuestra con la linea de tendencia, la gran variedad de viajes aparentemente no son afectados por la precipitacion en el dia. Esto nos lleva a la conclusion de que el nivel de precipitaciones no tiene una relacion lo suficientemente fuerte con la duracion de cada viaje como para mostrar un gran cambio en este, aunque parte de la Ciencia de Datos también incluye la interpretacion de datos, y sería negligente no mencionar que la mayoria de días con precipitaciones mayores a 0mm tuvieron lluvias de 5mm o menos, es decir, una llovizna. Ademas de esto, no tenemos los datos de las precipitaciones horarias, por lo que no podemos comparar el nivel de lluvia de cada momento con los viajes realizados en esos momentos; y por si todavía no lo aclaramos, la mayoría de los viajes tiene una corta duración, lo cual dificulta aún más ver si las precipitaciones afectaron a la duración de los viajes.
Ahora, con el dataframe que creamos para el gráfico anterior (que contiene el promedio de duracion de viaje de cada día), podemos comparar esta variable con la temperatura promedio diaria y buscar una relación entre estas variables:
ggplot(union %>% inner_join(promedio_duracion,by="fecha") %>% distinct(fecha, .keep_all = T), aes(
x=tavg,
y=promedio
)) + geom_point() + geom_smooth(method="lm") +
theme_bw()+ labs(x = "Temperatura Promedio(tavg)", y = "Promedio duración de viajes", title = "Promedio de duración de viajes según la temperatura promedio")Como se puede ver con la línea de tendencia, la duración promedio de viaje aumenta ligeramente conforme la temperatura promedio de cada día, mostrando que la temperatura afecta a la cantidad de tiempo que cada persona anda en EcoBici, con más temperatura teniendo un efecto ligeramente positivo en este, aunque no se muestra la relación que tiene esta variable con la cantidad de viajes diarios en EcoBici, la podemos ver en el siguiente diagrama:
ggplot(union %>% inner_join(conteo_fechas,by="fecha") %>% distinct(fecha, .keep_all=T),aes(
x=tavg,
y=Freq, colour= trabajo
)) + geom_point() + geom_smooth(se=F) +
labs(x = "Temperatura Promedio(tavg)", y = "Cantidad de viajes diarios", title = "Cantidad de viajes según la temperatura promedio")En este gráfico, consideramos importante usar una linea de tendencia con un modelo no lineal, ya que ocultaria informacion importante para la interpretacion de datos. Esto se debe a que se puede ver un cambio en el uso de EcoBicis en temperaturas extremas, sean estas muy bajas o muy altas, pero un uso normal entre alrededor de los 15 y 25 grados celsius aproximadamente. Desde aqui, podemos inferir que la temperatura afecta a la cantidad de viajes en EcoBici, con las temperaturas más frías o más calientes señalando un uso reducido de EcoBicis.
Y se puede destacar que la variable de Dia laborable o no laborable es muy importante si se busca predecir el uso de las bicicletas, pues se puede ver una clara agrupación de los puntos rojos y azules, teniendo los rojos una cantidad de viajes considerablemente mayor que los azules.
Más allá del ambiente climático diario, es tambien útil ver la cantidad de viajes hechos en cada temporada del año, así pudiendo rastrear las tendencias de viajes, para lo cual organizamos el siguiente diagrama:
ggplot (union, aes(
x = estacion_año, fill=estacion_año
)) + geom_bar() +
theme_gray()+
labs(x = "Estación del año", y = "Cantidad de viajes", title = "Cantidad de viajes por estación")Acá podemos ver que la mayoría de viajes se realizaron en primavera, que de por sí no sería lo suficientemente relevante para un análisis exploratorio, pero un tema importante en la Ciencia de Datos es la búsqueda de patrones entre la informacion. Para apoyar este gráfico, y este aspecto de la ciencia, usaremos la siguiente tabla, que muestra las temperaturas promedio por estacion:
temp_promedio <- union %>% group_by(estacion_año) %>% summarize(temp_promedio = mean(tavg))
temp_promedio# A tibble: 4 × 2
estacion_año temp_promedio
<chr> <dbl>
1 Invierno 13.1
2 Otoño 15.6
3 Primavera 20.2
4 Verano 23.3
Ahora, podemos relacionar tres importantes piezas de datos, el gráfico de barras que muestra los viajes por estación, el cuadro que detalla la temperatura promedio estacional y el gráfico de puntos que indica el uso de ecobicis en funcion de la temperatura. Con estas tres piezas de información, resulta fácil encontrar patrones, ya que desde acá podemos extrapolar el por qué hay un elevado uso de EcoBicis en primavera, y esto se debe a que las temperaturas durante esta estación, están en un promedio de 20 grados, y usando el gráfico de temperaturas anterior, vemos que la línea de tendencia llega a un pico en, justamente, 20 grados, mientras que las demás temperaturas promedio, aunque estén alrededor de este rango, no alcanzan a la temperatura óptima que es el promedio en primavera. Usando tres simples maneras de visualizar la información, podemos inferir una de las razones del uso elevado de EcoBicis en esta estación, lo cual se ve reforzado por el siguiente gráfico, que son los viajes en funcion de la temperatura pero esta vez, agregando las estaciones del año:
ggplot(union %>% inner_join(conteo_fechas,by="fecha") %>% distinct(fecha, .keep_all=T),aes(
x=tavg,
y=Freq,
color = estacion_año
)) + geom_boxplot() + labs(x = "Temperatura Promedio (tavg)", y = "Cantidad de viajes", title = "Viajes en función de la temperatura en cada estación del año")En efecto, se puede observar que los días en primavera se encuentran alrededor de los 20 grados, la temperatura óptima según descubrimos, mientras que las demás estaciones se encuentran en rangos alrededor de temperaturas más bajas o altas, alejándose de donde se alcanza el pico. No solo eso, sino podemos ver que la frecuencia más alta se encuentra en primavera, reforzando aún más la razon de por qué hay más viajes en esta estación.
Ahora, más allá de las tendencias estacionales del uso de EcoBici, podemos pasar a centrarnos en los usos de EcoBicis en función de las horas del día. Para esto, usaremos la siguiente función para separar los horarios de EcoBicis entre fecha y hora de salida y de llegada por separado:
#Dejamos solo la hora. Y lo pasamos a tipo integer
union <- union %>%
mutate(hora_origen_recorrido = as.integer(format(fecha_origen_recorrido, format = "%H")),hora_destino_recorrido=as.integer(format(fecha_destino_recorrido,format = "%H")))
#Gráfico en función de la hora de origen
ggplot(union, aes(x=hora_origen_recorrido ))+ geom_bar(fill="yellow", colour="red") + theme_classic()+
labs(x = "Hora Origen)", y = "Cantidad de viajes", title = "Grafico de los viajes en función de la hora de origen")#Gráfico en función de la hora del destino
ggplot(union, aes(x=hora_destino_recorrido))+ geom_bar(fill="yellow", colour="red")+ theme_classic()+
labs(x = "Hora Destino)", y = "Cantidad de viajes", title = "Grafico de los viajes en función de hora de llegada")Se puede ver un panorama general de a qué hora empiezan los viajes, pero un detalle importante es que la mayoría empieza y termina en la misma hora (Los viajes no duran más de una hora, y en realidad esa diferencia entre hora de origen y hora de llegada se da porque alguien empieza por ejemplo, un viaje a las 14:50hs y lo termina a las 15:05). Si los viajes fueran más largos se podría apreciar alguna diferencia mínima, pero así como está sirve para tener un panorama de a qué hora se realizan los trayectos.
Cierre
Aquí damos por finalizado este trabajo práctico donde hicimos un análisis extensivo del dataset de EcoBicis y del dataset de las temperaturas en 2022; primero de forma individual (análisis descriptivo), y luego de forma grupal, combinando ambos datasets (análisis exploratorio), donde en éste último tipo de análisis pudimos sacar conclusiones acerca de la información que portaban estos datos.
Bibliografia
Datos del uso de EcoBicis: https://data.buenosaires.gob.ar/dataset/bicicletas-publicas
Datos del clima durante 2022: https://meteostat.net/es/station/87582?t=2022-01-01/2022-12-31
Clasificación de la intensidad del viento: https://www.smn.gob.ar/noticias/%C2%BFc%C3%B3mo-clasificamos-la-intensidad-del-viento
Librerías usadas: lubridate, dplyr, readr, ggplot2, tidyr, geosphere y leaflet